//===----------------------------------------------------------------------===//
//
// This source file is part of the Soto for AWS open source project
//
// Copyright (c) 2017-2022 the Soto project authors
// Licensed under Apache License v2.0
//
// See LICENSE.txt for license information
// See CONTRIBUTORS.txt for the list of Soto project authors
//
// SPDX-License-Identifier: Apache-2.0
//
//===----------------------------------------------------------------------===//

// THIS FILE IS AUTOMATICALLY GENERATED by https://github.com/soto-project/soto-codegenerator.
// DO NOT EDIT.

import Foundation
import SotoCore

extension RolesAnywhere {
    // MARK: Enums

    public enum TrustAnchorType: String, CustomStringConvertible, Codable, _SotoSendable {
        case awsAcmPca = "AWS_ACM_PCA"
        case certificateBundle = "CERTIFICATE_BUNDLE"
        case selfSignedRepository = "SELF_SIGNED_REPOSITORY"
        public var description: String { return self.rawValue }
    }

    public enum SourceData: AWSEncodableShape & AWSDecodableShape, _SotoSendable {
        /// The root certificate of the Certificate Manager Private Certificate Authority specified by this ARN is used in trust validation for CreateSession operations. Included for trust anchors of type AWS_ACM_PCA.
        case acmPcaArn(String)
        /// The PEM-encoded data for the certificate anchor. Included for trust anchors of type CERTIFICATE_BUNDLE.
        case x509CertificateData(String)

        public init(from decoder: Decoder) throws {
            let container = try decoder.container(keyedBy: CodingKeys.self)
            guard container.allKeys.count == 1, let key = container.allKeys.first else {
                let context = DecodingError.Context(
                    codingPath: container.codingPath,
                    debugDescription: "Expected exactly one key, but got \(container.allKeys.count)"
                )
                throw DecodingError.dataCorrupted(context)
            }
            switch key {
            case .acmPcaArn:
                let value = try container.decode(String.self, forKey: .acmPcaArn)
                self = .acmPcaArn(value)
            case .x509CertificateData:
                let value = try container.decode(String.self, forKey: .x509CertificateData)
                self = .x509CertificateData(value)
            }
        }

        public func encode(to encoder: Encoder) throws {
            var container = encoder.container(keyedBy: CodingKeys.self)
            switch self {
            case .acmPcaArn(let value):
                try container.encode(value, forKey: .acmPcaArn)
            case .x509CertificateData(let value):
                try container.encode(value, forKey: .x509CertificateData)
            }
        }

        private enum CodingKeys: String, CodingKey {
            case acmPcaArn
            case x509CertificateData
        }
    }

    // MARK: Shapes

    public struct CreateProfileRequest: AWSEncodableShape {
        ///  The number of seconds the vended session credentials are valid for.
        public let durationSeconds: Int?
        /// Specifies whether the profile is enabled.
        public let enabled: Bool?
        /// A list of managed policy ARNs that apply to the vended session credentials.
        public let managedPolicyArns: [String]?
        /// The name of the profile.
        public let name: String
        /// Specifies whether instance properties are required in CreateSession requests with this profile.
        public let requireInstanceProperties: Bool?
        /// A list of IAM roles that this profile can assume in a CreateSession operation.
        public let roleArns: [String]
        /// A session policy that applies to the trust boundary of the vended session credentials.
        public let sessionPolicy: String?
        /// The tags to attach to the profile.
        public let tags: [Tag]?

        public init(durationSeconds: Int? = nil, enabled: Bool? = nil, managedPolicyArns: [String]? = nil, name: String, requireInstanceProperties: Bool? = nil, roleArns: [String], sessionPolicy: String? = nil, tags: [Tag]? = nil) {
            self.durationSeconds = durationSeconds
            self.enabled = enabled
            self.managedPolicyArns = managedPolicyArns
            self.name = name
            self.requireInstanceProperties = requireInstanceProperties
            self.roleArns = roleArns
            self.sessionPolicy = sessionPolicy
            self.tags = tags
        }

        public func validate(name: String) throws {
            try self.validate(self.managedPolicyArns, name: "managedPolicyArns", parent: name, max: 50)
            try self.validate(self.name, name: "name", parent: name, max: 255)
            try self.validate(self.name, name: "name", parent: name, min: 1)
            try self.validate(self.name, name: "name", parent: name, pattern: "^[ a-zA-Z0-9-_]*$")
            try self.roleArns.forEach {
                try validate($0, name: "roleArns[]", parent: name, max: 1011)
                try validate($0, name: "roleArns[]", parent: name, min: 1)
                try validate($0, name: "roleArns[]", parent: name, pattern: "^arn:aws(-[^:]+)?:iam(:.*){2}(:role.*)$")
            }
            try self.validate(self.roleArns, name: "roleArns", parent: name, max: 50)
            try self.tags?.forEach {
                try $0.validate(name: "\(name).tags[]")
            }
            try self.validate(self.tags, name: "tags", parent: name, max: 50)
        }

        private enum CodingKeys: String, CodingKey {
            case durationSeconds
            case enabled
            case managedPolicyArns
            case name
            case requireInstanceProperties
            case roleArns
            case sessionPolicy
            case tags
        }
    }

    public struct CreateTrustAnchorRequest: AWSEncodableShape {
        /// Specifies whether the trust anchor is enabled.
        public let enabled: Bool?
        /// The name of the trust anchor.
        public let name: String
        /// The trust anchor type and its related certificate data.
        public let source: Source
        /// The tags to attach to the trust anchor.
        public let tags: [Tag]?

        public init(enabled: Bool? = nil, name: String, source: Source, tags: [Tag]? = nil) {
            self.enabled = enabled
            self.name = name
            self.source = source
            self.tags = tags
        }

        public func validate(name: String) throws {
            try self.validate(self.name, name: "name", parent: name, max: 255)
            try self.validate(self.name, name: "name", parent: name, min: 1)
            try self.validate(self.name, name: "name", parent: name, pattern: "^[ a-zA-Z0-9-_]*$")
            try self.tags?.forEach {
                try $0.validate(name: "\(name).tags[]")
            }
            try self.validate(self.tags, name: "tags", parent: name, max: 50)
        }

        private enum CodingKeys: String, CodingKey {
            case enabled
            case name
            case source
            case tags
        }
    }

    public struct CredentialSummary: AWSDecodableShape {
        /// Indicates whether the credential is enabled.
        public let enabled: Bool?
        /// Indicates whether the CreateSession operation was successful.
        public let failed: Bool?
        /// The fully qualified domain name of the issuing certificate for the presented end-entity certificate.
        public let issuer: String?
        /// The ISO-8601 time stamp of when the certificate was last used in a CreateSession operation.
        public let seenAt: Date?
        /// The serial number of the certificate.
        public let serialNumber: String?
        /// The PEM-encoded data of the certificate.
        public let x509CertificateData: String?

        public init(enabled: Bool? = nil, failed: Bool? = nil, issuer: String? = nil, seenAt: Date? = nil, serialNumber: String? = nil, x509CertificateData: String? = nil) {
            self.enabled = enabled
            self.failed = failed
            self.issuer = issuer
            self.seenAt = seenAt
            self.serialNumber = serialNumber
            self.x509CertificateData = x509CertificateData
        }

        private enum CodingKeys: String, CodingKey {
            case enabled
            case failed
            case issuer
            case seenAt
            case serialNumber
            case x509CertificateData
        }
    }

    public struct CrlDetail: AWSDecodableShape {
        /// The ISO-8601 timestamp when the certificate revocation list (CRL) was created.
        public let createdAt: Date?
        /// The ARN of the certificate revocation list (CRL).
        public let crlArn: String?
        /// The state of the certificate revocation list (CRL) after a read or write operation.
        public let crlData: AWSBase64Data?
        /// The unique identifier of the certificate revocation list (CRL).
        public let crlId: String?
        /// Indicates whether the certificate revocation list (CRL) is enabled.
        public let enabled: Bool?
        /// The name of the certificate revocation list (CRL).
        public let name: String?
        /// The ARN of the TrustAnchor the certificate revocation list (CRL) will provide revocation for.
        public let trustAnchorArn: String?
        /// The ISO-8601 timestamp when the certificate revocation list (CRL) was last updated.
        public let updatedAt: Date?

        public init(createdAt: Date? = nil, crlArn: String? = nil, crlData: AWSBase64Data? = nil, crlId: String? = nil, enabled: Bool? = nil, name: String? = nil, trustAnchorArn: String? = nil, updatedAt: Date? = nil) {
            self.createdAt = createdAt
            self.crlArn = crlArn
            self.crlData = crlData
            self.crlId = crlId
            self.enabled = enabled
            self.name = name
            self.trustAnchorArn = trustAnchorArn
            self.updatedAt = updatedAt
        }

        private enum CodingKeys: String, CodingKey {
            case createdAt
            case crlArn
            case crlData
            case crlId
            case enabled
            case name
            case trustAnchorArn
            case updatedAt
        }
    }

    public struct CrlDetailResponse: AWSDecodableShape {
        /// The state of the certificate revocation list (CRL) after a read or write operation.
        public let crl: CrlDetail

        public init(crl: CrlDetail) {
            self.crl = crl
        }

        private enum CodingKeys: String, CodingKey {
            case crl
        }
    }

    public struct ImportCrlRequest: AWSEncodableShape {
        /// The x509 v3 specified certificate revocation list
        public let crlData: AWSBase64Data
        /// Specifies whether the certificate revocation list (CRL) is enabled.
        public let enabled: Bool?
        /// The name of the certificate revocation list (CRL).
        public let name: String
        /// A list of tags to attach to the certificate revocation list (CRL).
        public let tags: [Tag]?
        /// The ARN of the TrustAnchor the certificate revocation list (CRL) will provide revocation for.
        public let trustAnchorArn: String

        public init(crlData: AWSBase64Data, enabled: Bool? = nil, name: String, tags: [Tag]? = nil, trustAnchorArn: String) {
            self.crlData = crlData
            self.enabled = enabled
            self.name = name
            self.tags = tags
            self.trustAnchorArn = trustAnchorArn
        }

        public func validate(name: String) throws {
            try self.validate(self.name, name: "name", parent: name, max: 255)
            try self.validate(self.name, name: "name", parent: name, min: 1)
            try self.validate(self.name, name: "name", parent: name, pattern: "^[ a-zA-Z0-9-_]*$")
            try self.tags?.forEach {
                try $0.validate(name: "\(name).tags[]")
            }
            try self.validate(self.tags, name: "tags", parent: name, max: 50)
            try self.validate(self.trustAnchorArn, name: "trustAnchorArn", parent: name, max: 1011)
            try self.validate(self.trustAnchorArn, name: "trustAnchorArn", parent: name, min: 1)
            try self.validate(self.trustAnchorArn, name: "trustAnchorArn", parent: name, pattern: "^arn:aws(-[^:]+)?:rolesanywhere(:.*){2}(:trust-anchor.*)$")
        }

        private enum CodingKeys: String, CodingKey {
            case crlData
            case enabled
            case name
            case tags
            case trustAnchorArn
        }
    }

    public struct InstanceProperty: AWSDecodableShape {
        /// Indicates whether the CreateSession operation was successful.
        public let failed: Bool?
        /// A list of instanceProperty objects.
        public let properties: [String: String]?
        /// The ISO-8601 time stamp of when the certificate was last used in a CreateSession operation.
        public let seenAt: Date?

        public init(failed: Bool? = nil, properties: [String: String]? = nil, seenAt: Date? = nil) {
            self.failed = failed
            self.properties = properties
            self.seenAt = seenAt
        }

        private enum CodingKeys: String, CodingKey {
            case failed
            case properties
            case seenAt
        }
    }

    public struct ListCrlsResponse: AWSDecodableShape {
        /// A list of certificate revocation lists (CRL).
        public let crls: [CrlDetail]?
        /// A token that indicates where the output should continue from, if a previous operation did not show all results. To get the next results, call the operation again with this value.
        public let nextToken: String?

        public init(crls: [CrlDetail]? = nil, nextToken: String? = nil) {
            self.crls = crls
            self.nextToken = nextToken
        }

        private enum CodingKeys: String, CodingKey {
            case crls
            case nextToken
        }
    }

    public struct ListProfilesResponse: AWSDecodableShape {
        /// A token that indicates where the output should continue from, if a previous operation did not show all results. To get the next results, call the operation again with this value.
        public let nextToken: String?
        /// A list of profiles.
        public let profiles: [ProfileDetail]?

        public init(nextToken: String? = nil, profiles: [ProfileDetail]? = nil) {
            self.nextToken = nextToken
            self.profiles = profiles
        }

        private enum CodingKeys: String, CodingKey {
            case nextToken
            case profiles
        }
    }

    public struct ListRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "nextToken", location: .querystring("nextToken")),
            AWSMemberEncoding(label: "pageSize", location: .querystring("pageSize"))
        ]

        /// A token that indicates where the output should continue from, if a previous operation did not show all results. To get the next results, call the operation again with this value.
        public let nextToken: String?
        /// The number of resources in the paginated list.
        public let pageSize: Int?

        public init(nextToken: String? = nil, pageSize: Int? = nil) {
            self.nextToken = nextToken
            self.pageSize = pageSize
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct ListSubjectsResponse: AWSDecodableShape {
        /// A token that indicates where the output should continue from, if a previous operation did not show all results. To get the next results, call the operation again with this value.
        public let nextToken: String?
        /// A list of subjects.
        public let subjects: [SubjectSummary]?

        public init(nextToken: String? = nil, subjects: [SubjectSummary]? = nil) {
            self.nextToken = nextToken
            self.subjects = subjects
        }

        private enum CodingKeys: String, CodingKey {
            case nextToken
            case subjects
        }
    }

    public struct ListTagsForResourceRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "resourceArn", location: .querystring("resourceArn"))
        ]

        /// The ARN of the resource.
        public let resourceArn: String

        public init(resourceArn: String) {
            self.resourceArn = resourceArn
        }

        public func validate(name: String) throws {
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, max: 1011)
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, min: 1)
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct ListTagsForResourceResponse: AWSDecodableShape {
        /// A list of tags attached to the resource.
        public let tags: [Tag]?

        public init(tags: [Tag]? = nil) {
            self.tags = tags
        }

        private enum CodingKeys: String, CodingKey {
            case tags
        }
    }

    public struct ListTrustAnchorsResponse: AWSDecodableShape {
        /// A token that indicates where the output should continue from, if a previous operation did not show all results. To get the next results, call the operation again with this value.
        public let nextToken: String?
        /// A list of trust anchors.
        public let trustAnchors: [TrustAnchorDetail]?

        public init(nextToken: String? = nil, trustAnchors: [TrustAnchorDetail]? = nil) {
            self.nextToken = nextToken
            self.trustAnchors = trustAnchors
        }

        private enum CodingKeys: String, CodingKey {
            case nextToken
            case trustAnchors
        }
    }

    public struct ProfileDetail: AWSDecodableShape {
        /// The ISO-8601 timestamp when the profile was created.
        public let createdAt: Date?
        /// The Amazon Web Services account that created the profile.
        public let createdBy: String?
        ///  The number of seconds the vended session credentials are valid for.
        public let durationSeconds: Int?
        /// Indicates whether the profile is enabled.
        public let enabled: Bool?
        /// A list of managed policy ARNs that apply to the vended session credentials.
        public let managedPolicyArns: [String]?
        /// The name of the profile.
        public let name: String?
        /// The ARN of the profile.
        public let profileArn: String?
        /// The unique identifier of the profile.
        public let profileId: String?
        /// Specifies whether instance properties are required in CreateSession requests with this profile.
        public let requireInstanceProperties: Bool?
        /// A list of IAM roles that this profile can assume in a CreateSession operation.
        public let roleArns: [String]?
        /// A session policy that applies to the trust boundary of the vended session credentials.
        public let sessionPolicy: String?
        /// The ISO-8601 timestamp when the profile was last updated.
        public let updatedAt: Date?

        public init(createdAt: Date? = nil, createdBy: String? = nil, durationSeconds: Int? = nil, enabled: Bool? = nil, managedPolicyArns: [String]? = nil, name: String? = nil, profileArn: String? = nil, profileId: String? = nil, requireInstanceProperties: Bool? = nil, roleArns: [String]? = nil, sessionPolicy: String? = nil, updatedAt: Date? = nil) {
            self.createdAt = createdAt
            self.createdBy = createdBy
            self.durationSeconds = durationSeconds
            self.enabled = enabled
            self.managedPolicyArns = managedPolicyArns
            self.name = name
            self.profileArn = profileArn
            self.profileId = profileId
            self.requireInstanceProperties = requireInstanceProperties
            self.roleArns = roleArns
            self.sessionPolicy = sessionPolicy
            self.updatedAt = updatedAt
        }

        private enum CodingKeys: String, CodingKey {
            case createdAt
            case createdBy
            case durationSeconds
            case enabled
            case managedPolicyArns
            case name
            case profileArn
            case profileId
            case requireInstanceProperties
            case roleArns
            case sessionPolicy
            case updatedAt
        }
    }

    public struct ProfileDetailResponse: AWSDecodableShape {
        /// The state of the profile after a read or write operation.
        public let profile: ProfileDetail?

        public init(profile: ProfileDetail? = nil) {
            self.profile = profile
        }

        private enum CodingKeys: String, CodingKey {
            case profile
        }
    }

    public struct ScalarCrlRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "crlId", location: .uri("crlId"))
        ]

        /// The unique identifier of the certificate revocation list (CRL).
        public let crlId: String

        public init(crlId: String) {
            self.crlId = crlId
        }

        public func validate(name: String) throws {
            try self.validate(self.crlId, name: "crlId", parent: name, max: 36)
            try self.validate(self.crlId, name: "crlId", parent: name, min: 36)
            try self.validate(self.crlId, name: "crlId", parent: name, pattern: "[a-f0-9]{8}-([a-z0-9]{4}-){3}[a-z0-9]{12}")
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct ScalarProfileRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "profileId", location: .uri("profileId"))
        ]

        /// The unique identifier of the profile.
        public let profileId: String

        public init(profileId: String) {
            self.profileId = profileId
        }

        public func validate(name: String) throws {
            try self.validate(self.profileId, name: "profileId", parent: name, max: 36)
            try self.validate(self.profileId, name: "profileId", parent: name, min: 36)
            try self.validate(self.profileId, name: "profileId", parent: name, pattern: "[a-f0-9]{8}-([a-z0-9]{4}-){3}[a-z0-9]{12}")
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct ScalarSubjectRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "subjectId", location: .uri("subjectId"))
        ]

        /// The unique identifier of the subject.
        public let subjectId: String

        public init(subjectId: String) {
            self.subjectId = subjectId
        }

        public func validate(name: String) throws {
            try self.validate(self.subjectId, name: "subjectId", parent: name, max: 36)
            try self.validate(self.subjectId, name: "subjectId", parent: name, min: 36)
            try self.validate(self.subjectId, name: "subjectId", parent: name, pattern: "[a-f0-9]{8}-([a-z0-9]{4}-){3}[a-z0-9]{12}")
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct ScalarTrustAnchorRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "trustAnchorId", location: .uri("trustAnchorId"))
        ]

        /// The unique identifier of the trust anchor.
        public let trustAnchorId: String

        public init(trustAnchorId: String) {
            self.trustAnchorId = trustAnchorId
        }

        public func validate(name: String) throws {
            try self.validate(self.trustAnchorId, name: "trustAnchorId", parent: name, max: 36)
            try self.validate(self.trustAnchorId, name: "trustAnchorId", parent: name, min: 36)
            try self.validate(self.trustAnchorId, name: "trustAnchorId", parent: name, pattern: "[a-f0-9]{8}-([a-z0-9]{4}-){3}[a-z0-9]{12}")
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct Source: AWSEncodableShape & AWSDecodableShape {
        /// The data field of the trust anchor depending on its type.
        public let sourceData: SourceData?
        /// The type of the trust anchor.
        public let sourceType: TrustAnchorType?

        public init(sourceData: SourceData? = nil, sourceType: TrustAnchorType? = nil) {
            self.sourceData = sourceData
            self.sourceType = sourceType
        }

        private enum CodingKeys: String, CodingKey {
            case sourceData
            case sourceType
        }
    }

    public struct SubjectDetail: AWSDecodableShape {
        /// The ISO-8601 timestamp when the subject was created.
        public let createdAt: Date?
        /// The temporary session credentials vended at the last authenticating call with this Subject.
        public let credentials: [CredentialSummary]?
        /// The enabled status of the subject.
        public let enabled: Bool?
        /// The specified instance properties associated with the request.
        public let instanceProperties: [InstanceProperty]?
        /// The ISO-8601 timestamp of the last time this Subject requested temporary session credentials.
        public let lastSeenAt: Date?
        /// The ARN of the resource.
        public let subjectArn: String?
        /// The id of the resource
        public let subjectId: String?
        /// The ISO-8601 timestamp when the subject was last updated.
        public let updatedAt: Date?
        /// The x509 principal identifier of the authenticating certificate.
        public let x509Subject: String?

        public init(createdAt: Date? = nil, credentials: [CredentialSummary]? = nil, enabled: Bool? = nil, instanceProperties: [InstanceProperty]? = nil, lastSeenAt: Date? = nil, subjectArn: String? = nil, subjectId: String? = nil, updatedAt: Date? = nil, x509Subject: String? = nil) {
            self.createdAt = createdAt
            self.credentials = credentials
            self.enabled = enabled
            self.instanceProperties = instanceProperties
            self.lastSeenAt = lastSeenAt
            self.subjectArn = subjectArn
            self.subjectId = subjectId
            self.updatedAt = updatedAt
            self.x509Subject = x509Subject
        }

        private enum CodingKeys: String, CodingKey {
            case createdAt
            case credentials
            case enabled
            case instanceProperties
            case lastSeenAt
            case subjectArn
            case subjectId
            case updatedAt
            case x509Subject
        }
    }

    public struct SubjectDetailResponse: AWSDecodableShape {
        /// The state of the subject after a read or write operation.
        public let subject: SubjectDetail?

        public init(subject: SubjectDetail? = nil) {
            self.subject = subject
        }

        private enum CodingKeys: String, CodingKey {
            case subject
        }
    }

    public struct SubjectSummary: AWSDecodableShape {
        /// The ISO-8601 time stamp of when the certificate was first used in a CreateSession operation.
        public let createdAt: Date?
        /// The enabled status of the Subject.
        public let enabled: Bool?
        /// The ISO-8601 time stamp of when the certificate was last used in a CreateSession operation.
        public let lastSeenAt: Date?
        /// The ARN of the resource.
        public let subjectArn: String?
        /// The id of the resource.
        public let subjectId: String?
        /// The ISO-8601 timestamp when the subject was last updated.
        public let updatedAt: Date?
        /// The x509 principal identifier of the authenticating certificate.
        public let x509Subject: String?

        public init(createdAt: Date? = nil, enabled: Bool? = nil, lastSeenAt: Date? = nil, subjectArn: String? = nil, subjectId: String? = nil, updatedAt: Date? = nil, x509Subject: String? = nil) {
            self.createdAt = createdAt
            self.enabled = enabled
            self.lastSeenAt = lastSeenAt
            self.subjectArn = subjectArn
            self.subjectId = subjectId
            self.updatedAt = updatedAt
            self.x509Subject = x509Subject
        }

        private enum CodingKeys: String, CodingKey {
            case createdAt
            case enabled
            case lastSeenAt
            case subjectArn
            case subjectId
            case updatedAt
            case x509Subject
        }
    }

    public struct Tag: AWSEncodableShape & AWSDecodableShape {
        /// The tag key.
        public let key: String
        /// The tag value.
        public let value: String

        public init(key: String, value: String) {
            self.key = key
            self.value = value
        }

        public func validate(name: String) throws {
            try self.validate(self.key, name: "key", parent: name, max: 128)
            try self.validate(self.key, name: "key", parent: name, min: 1)
            try self.validate(self.key, name: "key", parent: name, pattern: "^[ a-zA-Z0-9_.:/=+@-]*$")
            try self.validate(self.value, name: "value", parent: name, max: 256)
            try self.validate(self.value, name: "value", parent: name, pattern: "^[ a-zA-Z0-9_.:/=+@-]*$")
        }

        private enum CodingKeys: String, CodingKey {
            case key
            case value
        }
    }

    public struct TagResourceRequest: AWSEncodableShape {
        /// The ARN of the resource.
        public let resourceArn: String
        /// The tags to attach to the resource.
        public let tags: [Tag]

        public init(resourceArn: String, tags: [Tag]) {
            self.resourceArn = resourceArn
            self.tags = tags
        }

        public func validate(name: String) throws {
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, max: 1011)
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, min: 1)
            try self.tags.forEach {
                try $0.validate(name: "\(name).tags[]")
            }
            try self.validate(self.tags, name: "tags", parent: name, max: 50)
        }

        private enum CodingKeys: String, CodingKey {
            case resourceArn
            case tags
        }
    }

    public struct TagResourceResponse: AWSDecodableShape {
        public init() {}
    }

    public struct TrustAnchorDetail: AWSDecodableShape {
        /// The ISO-8601 timestamp when the trust anchor was created.
        public let createdAt: Date?
        /// Indicates whether the trust anchor is enabled.
        public let enabled: Bool?
        /// The name of the trust anchor.
        public let name: String?
        /// The trust anchor type and its related certificate data.
        public let source: Source?
        /// The ARN of the trust anchor.
        public let trustAnchorArn: String?
        /// The unique identifier of the trust anchor.
        public let trustAnchorId: String?
        /// The ISO-8601 timestamp when the trust anchor was last updated.
        public let updatedAt: Date?

        public init(createdAt: Date? = nil, enabled: Bool? = nil, name: String? = nil, source: Source? = nil, trustAnchorArn: String? = nil, trustAnchorId: String? = nil, updatedAt: Date? = nil) {
            self.createdAt = createdAt
            self.enabled = enabled
            self.name = name
            self.source = source
            self.trustAnchorArn = trustAnchorArn
            self.trustAnchorId = trustAnchorId
            self.updatedAt = updatedAt
        }

        private enum CodingKeys: String, CodingKey {
            case createdAt
            case enabled
            case name
            case source
            case trustAnchorArn
            case trustAnchorId
            case updatedAt
        }
    }

    public struct TrustAnchorDetailResponse: AWSDecodableShape {
        /// The state of the trust anchor after a read or write operation.
        public let trustAnchor: TrustAnchorDetail

        public init(trustAnchor: TrustAnchorDetail) {
            self.trustAnchor = trustAnchor
        }

        private enum CodingKeys: String, CodingKey {
            case trustAnchor
        }
    }

    public struct UntagResourceRequest: AWSEncodableShape {
        /// The ARN of the resource.
        public let resourceArn: String
        /// A list of keys. Tag keys are the unique identifiers of tags.
        public let tagKeys: [String]

        public init(resourceArn: String, tagKeys: [String]) {
            self.resourceArn = resourceArn
            self.tagKeys = tagKeys
        }

        public func validate(name: String) throws {
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, max: 1011)
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, min: 1)
            try self.tagKeys.forEach {
                try validate($0, name: "tagKeys[]", parent: name, max: 128)
                try validate($0, name: "tagKeys[]", parent: name, min: 1)
                try validate($0, name: "tagKeys[]", parent: name, pattern: "^[ a-zA-Z0-9_.:/=+@-]*$")
            }
            try self.validate(self.tagKeys, name: "tagKeys", parent: name, max: 50)
        }

        private enum CodingKeys: String, CodingKey {
            case resourceArn
            case tagKeys
        }
    }

    public struct UntagResourceResponse: AWSDecodableShape {
        public init() {}
    }

    public struct UpdateCrlRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "crlId", location: .uri("crlId"))
        ]

        /// The x509 v3 specified certificate revocation list
        public let crlData: AWSBase64Data?
        /// The unique identifier of the certificate revocation list (CRL).
        public let crlId: String
        /// The name of the Crl.
        public let name: String?

        public init(crlData: AWSBase64Data? = nil, crlId: String, name: String? = nil) {
            self.crlData = crlData
            self.crlId = crlId
            self.name = name
        }

        public func validate(name: String) throws {
            try self.validate(self.crlId, name: "crlId", parent: name, max: 36)
            try self.validate(self.crlId, name: "crlId", parent: name, min: 36)
            try self.validate(self.crlId, name: "crlId", parent: name, pattern: "[a-f0-9]{8}-([a-z0-9]{4}-){3}[a-z0-9]{12}")
            try self.validate(self.name, name: "name", parent: name, max: 255)
            try self.validate(self.name, name: "name", parent: name, min: 1)
            try self.validate(self.name, name: "name", parent: name, pattern: "^[ a-zA-Z0-9-_]*$")
        }

        private enum CodingKeys: String, CodingKey {
            case crlData
            case name
        }
    }

    public struct UpdateProfileRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "profileId", location: .uri("profileId"))
        ]

        ///  The number of seconds the vended session credentials are valid for.
        public let durationSeconds: Int?
        /// A list of managed policy ARNs that apply to the vended session credentials.
        public let managedPolicyArns: [String]?
        /// The name of the profile.
        public let name: String?
        /// The unique identifier of the profile.
        public let profileId: String
        /// A list of IAM roles that this profile can assume in a CreateSession operation.
        public let roleArns: [String]?
        /// A session policy that applies to the trust boundary of the vended session credentials.
        public let sessionPolicy: String?

        public init(durationSeconds: Int? = nil, managedPolicyArns: [String]? = nil, name: String? = nil, profileId: String, roleArns: [String]? = nil, sessionPolicy: String? = nil) {
            self.durationSeconds = durationSeconds
            self.managedPolicyArns = managedPolicyArns
            self.name = name
            self.profileId = profileId
            self.roleArns = roleArns
            self.sessionPolicy = sessionPolicy
        }

        public func validate(name: String) throws {
            try self.validate(self.managedPolicyArns, name: "managedPolicyArns", parent: name, max: 50)
            try self.validate(self.name, name: "name", parent: name, max: 255)
            try self.validate(self.name, name: "name", parent: name, min: 1)
            try self.validate(self.name, name: "name", parent: name, pattern: "^[ a-zA-Z0-9-_]*$")
            try self.validate(self.profileId, name: "profileId", parent: name, max: 36)
            try self.validate(self.profileId, name: "profileId", parent: name, min: 36)
            try self.validate(self.profileId, name: "profileId", parent: name, pattern: "[a-f0-9]{8}-([a-z0-9]{4}-){3}[a-z0-9]{12}")
            try self.roleArns?.forEach {
                try validate($0, name: "roleArns[]", parent: name, max: 1011)
                try validate($0, name: "roleArns[]", parent: name, min: 1)
                try validate($0, name: "roleArns[]", parent: name, pattern: "^arn:aws(-[^:]+)?:iam(:.*){2}(:role.*)$")
            }
            try self.validate(self.roleArns, name: "roleArns", parent: name, max: 50)
        }

        private enum CodingKeys: String, CodingKey {
            case durationSeconds
            case managedPolicyArns
            case name
            case roleArns
            case sessionPolicy
        }
    }

    public struct UpdateTrustAnchorRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "trustAnchorId", location: .uri("trustAnchorId"))
        ]

        /// The name of the trust anchor.
        public let name: String?
        /// The trust anchor type and its related certificate data.
        public let source: Source?
        /// The unique identifier of the trust anchor.
        public let trustAnchorId: String

        public init(name: String? = nil, source: Source? = nil, trustAnchorId: String) {
            self.name = name
            self.source = source
            self.trustAnchorId = trustAnchorId
        }

        public func validate(name: String) throws {
            try self.validate(self.name, name: "name", parent: name, max: 255)
            try self.validate(self.name, name: "name", parent: name, min: 1)
            try self.validate(self.name, name: "name", parent: name, pattern: "^[ a-zA-Z0-9-_]*$")
            try self.validate(self.trustAnchorId, name: "trustAnchorId", parent: name, max: 36)
            try self.validate(self.trustAnchorId, name: "trustAnchorId", parent: name, min: 36)
            try self.validate(self.trustAnchorId, name: "trustAnchorId", parent: name, pattern: "[a-f0-9]{8}-([a-z0-9]{4}-){3}[a-z0-9]{12}")
        }

        private enum CodingKeys: String, CodingKey {
            case name
            case source
        }
    }
}

// MARK: - Errors

/// Error enum for RolesAnywhere
public struct RolesAnywhereErrorType: AWSErrorType {
    enum Code: String {
        case accessDeniedException = "AccessDeniedException"
        case resourceNotFoundException = "ResourceNotFoundException"
        case tooManyTagsException = "TooManyTagsException"
        case validationException = "ValidationException"
    }

    private let error: Code
    public let context: AWSErrorContext?

    /// initialize RolesAnywhere
    public init?(errorCode: String, context: AWSErrorContext) {
        guard let error = Code(rawValue: errorCode) else { return nil }
        self.error = error
        self.context = context
    }

    internal init(_ error: Code) {
        self.error = error
        self.context = nil
    }

    /// return error code string
    public var errorCode: String { self.error.rawValue }

    /// You do not have sufficient access to perform this action.
    public static var accessDeniedException: Self { .init(.accessDeniedException) }
    /// The resource could not be found.
    public static var resourceNotFoundException: Self { .init(.resourceNotFoundException) }
    /// Too many tags.
    public static var tooManyTagsException: Self { .init(.tooManyTagsException) }
    /// Validation exception error.
    public static var validationException: Self { .init(.validationException) }
}

extension RolesAnywhereErrorType: Equatable {
    public static func == (lhs: RolesAnywhereErrorType, rhs: RolesAnywhereErrorType) -> Bool {
        lhs.error == rhs.error
    }
}

extension RolesAnywhereErrorType: CustomStringConvertible {
    public var description: String {
        return "\(self.error.rawValue): \(self.message ?? "")"
    }
}
